#include "firmwaredownload.hpp"

using namespace device;
using namespace ota;

#define FIRMWAREDOWNLOAD_STATE_ERASE				1
///>通过flash 进行操作
firmwaredownload::firmwaredownload(flash *tResourceFlash)
{
	mFirmWareDownloadFlash = tResourceFlash;
	CheckSumEnable = true;
	mFirmWareDownloadState = 0;
	mFirmWareDownloadIndex = 0;
}
///> 启动下载代码初始化，擦除下载区和信息区
bool firmwaredownload::Start(void)
{
	uint32_t i, j, k;
	if(mFirmWareDownloadFlash == NULL)
	{
		return(false);
	}
	j = OTA_FLASH_SIZE;
	k = mFirmWareDownloadFlash->GetSectorSize();
	j /= k;
	for(i = 0; i < j; i++)
	{
		if(!mFirmWareDownloadFlash->Erase(OTA_FLASH_ADDR + k * i))
		{
			mFirmWareDownloadState = FIRMWAREDOWNLOAD_STATE_ERASE;
			mFirmWareDownloadIndex = 0;
			return(false);
		}
	}
	if(!mFirmWareDownloadFlash->Erase(OTA_INF_FLASH_ADDR))
	{
		mFirmWareDownloadState = FIRMWAREDOWNLOAD_STATE_ERASE;
		mFirmWareDownloadIndex = 0;
		return(false);
	}
	mFirmWareDownloadState = FIRMWAREDOWNLOAD_STATE_ERASE;
	mFirmWareDownloadIndex = 0;
	return(true);
}

bool firmwaredownload::Stop(void)
{
	static uint8_t ucBuff[64];
	uint32_t uiCheckSum = 0;
	uint32_t i,j,k;
	if(mFirmWareDownloadFlash == NULL)
	{
		return(false);
	}
	if(!(mFirmWareDownloadState & FIRMWAREDOWNLOAD_STATE_ERASE))
	{
		return(false);
	}
	mFirmWareDownloadState = 0;
	mFirmWareDownloadIndex = 0;
	if(!CheckSumEnable)
	{
		return(true);
	}
	for(i = 0; i < FirmWareInfor.uiLength;)///>计算sum
	{
		j = FirmWareInfor.uiLength - i;
		if(j > 64)
		{
			j = 64;
		}
		if(!mFirmWareDownloadFlash->Read(OTA_FLASH_ADDR + i, ucBuff, j))
		{
			return(false);
		}
		for(k = 0; k < j; k++)
		{
			uiCheckSum += ucBuff[k];
		}
		i += j;
	}
	if(uiCheckSum != FirmWareInfor.uiPrgCheckSum)
	{
		return(false);
	}
	return(true);
}
///下载代码
bool firmwaredownload::WritePrg(uint32_t uiPackIndex, uint8_t *ucBuff, uint16_t usLen)
{
	if(mFirmWareDownloadFlash == NULL)
	{
		return(false);
	}
	if(!(mFirmWareDownloadState & FIRMWAREDOWNLOAD_STATE_ERASE))
	{
		return(false);
	}
	if(mFirmWareDownloadIndex != uiPackIndex)
	{
		return(false);
	}
	if(!mFirmWareDownloadFlash->Write(OTA_FLASH_ADDR + uiPackIndex * FirmWareInfor.uiPackLength, ucBuff, usLen))
	{
		return(false);
	}
	mFirmWareDownloadIndex++;
	return(true);
}

bool firmwaredownload::UpDatePrgInfor(void)
{
	if(mFirmWareDownloadFlash == NULL)
	{
		return(false);
	}
	if(!mFirmWareDownloadFlash->Erase(OTA_INF_FLASH_ADDR))
	{
		return(false);
	}
	FirmWareInfor.uiInforCheckSum = FirmWareInfor.uiLength + 
																	FirmWareInfor.uiNewVersion +
																	FirmWareInfor.uiOldVersion +
																	FirmWareInfor.uiPackLength +
																	FirmWareInfor.uiUpdateCount +
																	FirmWareInfor.uiPrgCheckSum + 
																	OTA_CHECKSUM;
	if(!mFirmWareDownloadFlash->Write(OTA_INF_FLASH_ADDR, (uint8_t *)&FirmWareInfor, sizeof(FirmWareInforTPDF)))
	{
		return(false);
	}
	return(true);
}

bool firmwaredownload::ReadPrgInfor(void)
{
	if(mFirmWareDownloadFlash == NULL)
	{
		return(false);
	}
	if(!mFirmWareDownloadFlash->Read(OTA_INF_FLASH_ADDR, (uint8_t *)&FirmWareInfor, sizeof(FirmWareInforTPDF)))
	{
		return(false);
	}
	return(true);
}

bool firmwaredownload::ReadPrgInfor(firmwaredownload::FirmWareInforTPDF *tFirmWareInfor)
{
	if(mFirmWareDownloadFlash == NULL)
	{
		return(false);
	}
	if(!mFirmWareDownloadFlash->Read(OTA_INF_FLASH_ADDR, (uint8_t *)tFirmWareInfor, sizeof(FirmWareInforTPDF)))
	{
		return(false);
	}
	return(true);
}

bool firmwaredownload::PrgInforUseable(FirmWareInforTPDF *tFirmWareInfor)
{
	uint32_t i = tFirmWareInfor->uiLength + 
							 tFirmWareInfor->uiNewVersion +
							 tFirmWareInfor->uiOldVersion +
							 tFirmWareInfor->uiPackLength +
							 tFirmWareInfor->uiUpdateCount +
							 tFirmWareInfor->uiPrgCheckSum + 
							 OTA_CHECKSUM;
	return(tFirmWareInfor->uiInforCheckSum == i);
}
